package com.newly.center.sys.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.newly.api.sys.feign.MenuClient;
import com.newly.center.sys.service.menu.api.IMenuService;
import com.newly.common.base.constants.MenuConstant;
import com.newly.common.base.constants.ServerUriConstant;
import com.newly.common.base.entity.PageUtils;
import com.newly.common.base.entity.R;
import com.newly.common.base.entity.sys.menu.dto.MenuDto;
import com.newly.common.base.entity.sys.menu.po.MenuPo;
import com.newly.common.base.entity.sys.menu.vo.MenuAbilityVo;
import com.newly.common.base.entity.sys.menu.vo.MenuRenderRuleVo;
import com.newly.common.base.entity.sys.menu.vo.MenuTypeVo;
import com.newly.common.base.entity.sys.menu.vo.MenuVo;
import com.newly.common.base.entity.sys.menu.xml.MenuItemsXml;
import com.newly.common.base.entity.sys.tenant.bo.SimpleTenantBo;
import com.newly.common.base.entity.sys.tenant.vo.SimpleTenantVo;
import com.newly.common.core.utils.RequestUtils;
import com.newly.common.core.utils.ResponseUtils;
import com.newly.common.core.utils.XmlUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.net.URL;
import java.util.List;
import java.util.Map;

/**
 * @author gjm guan
 * @date 2021/10/2 10:44
 * @desc 菜单api
 */
@RestController
@RequestMapping(ServerUriConstant.NEWLY_SYS_MENU)
public class MenuApi implements MenuClient {

    @Autowired
    private IMenuService menuService;

    @Autowired
    private ResponseUtils responseUtils;

    @Autowired
    private RequestUtils requestUtils;

    @Override
    public R create(MenuDto menuDto) {
        boolean result = false;
        try {
            Integer menuId = menuService.save(menuDto);
            result = menuId != null;
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(result);
    }

    @Override
    public R deleteByIds(List<Integer> menuIds) {
        boolean result = false;
        try {
            result = menuService.removeByIds(menuIds);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(result);
    }

    @Override
    public R refreshCache() {
        boolean result = false;
        try {
            result = menuService.refreshCache();
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(result);
    }

    @Override
    public R change(MenuDto menuDto) {
        boolean result = false;
        try {
            result = menuService.modifyById(menuDto);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(result);
    }

    @Override
    public R changeSortById(Integer menuId, Integer sort) {
        boolean result = false;
        try {
            result = menuService.modifySortById(menuId, sort);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(result);
    }

    @Override
    public void exportTemplate(HttpServletResponse response) {
        requestUtils.getCurrentTenant().assertIsDev();
        URL resource = MenuApi.class.getClassLoader().getResource(MenuConstant.MENU_TEMPLATE_FILE_NAME);
        responseUtils.download(resource.getPath(), MenuConstant.MENU_TEMPLATE_FILE_NAME, response);
    }

    @Override
    public R exportXml(List<Integer> menuIds, HttpServletResponse response) {
        String xmlStr = null;
        try {
            MenuItemsXml exportDatum = menuService.getExportDatum(menuIds);
            xmlStr = XmlUtils.objToXmlStr(exportDatum);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(xmlStr);
    }

    @Override
    public R importXml(MultipartFile multipartFile) {
        boolean result = false;
        try {
            MenuItemsXml menuItemsXml = menuService.getImportDatum(multipartFile);
            List<MenuDto> menuDtos = BeanUtil.copyToList(menuItemsXml.getMenu(), MenuDto.class);
            result = menuService.saveAll(menuDtos);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(result);
    }

    @Override
    public R list(Integer offset, Integer limit, Integer abilityCode, Integer typeCode,
                  Long createBy, String keyword) {
        PageUtils pageUtils = null;
        List<MenuVo> menuVos = null;
        try {
            List<MenuPo> menuPos = menuService.list(offset, limit, abilityCode, typeCode, createBy, keyword);
            if (!ObjectUtil.isEmpty(menuPos)) {
                menuVos = BeanUtil.copyToList(menuPos, MenuVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuVos);
    }

    @Override
    public R queryInAuth() {
        List<MenuVo> menuVos = null;
        try {
            List<MenuPo> menuPos = menuService.getInAuth();
            if (!ObjectUtil.isEmpty(menuPos)) {
                menuVos = BeanUtil.copyToList(menuPos, MenuVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuVos);
    }

    @Override
    public R queryPermListInAuth() {
        List<MenuVo> menuVos = null;
        try {
            List<MenuPo> menuPos = menuService.getPermListInAuth();
            if (!ObjectUtil.isEmpty(menuPos)) {
                menuVos = BeanUtil.copyToList(menuPos, MenuVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuVos);
    }

    @Override
    public R queryLayoutInAuth() {
        List<MenuVo> menuVos = null;
        try {
            List<MenuPo> menuPos = menuService.getLayoutInAuth();
            if (!ObjectUtil.isEmpty(menuPos)) {
                menuVos = BeanUtil.copyToList(menuPos, MenuVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuVos);
    }

    @Override
    public R queryPageInnerInAuth(Integer menuId) {
        List<MenuVo> menuVos = null;
        try {
            List<MenuPo> menuPos = menuService.getPageInnerInAuth(menuId);
            if (!ObjectUtil.isEmpty(menuPos)) {
                menuVos = BeanUtil.copyToList(menuPos, MenuVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuVos);
    }

    @Override
    public R listMenuAbilityMapInAuth() {
        Map<Integer, Map<String, MenuAbilityVo>> abilityMap = null;
        try {
            abilityMap = menuService.listMenuAbilityMapInAuth();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.ok(abilityMap);
    }

    @Override
    public R queryTypes() {
        List<MenuTypeVo> menuTypeVos = null;
        try {
            menuTypeVos = menuService.getTypes();
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuTypeVos);
    }

    @Override
    public R queryAbility() {
        List<MenuAbilityVo> menuAbilityVos = null;
        try {
            menuAbilityVos = menuService.getAbility();
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuAbilityVos);
    }

    @Override
    public R queryCreateTenant() {
        List<SimpleTenantVo> simpleTenantVos = null;
        try {
            List<SimpleTenantBo> simpleTenantBos = menuService.getCreateTenant();
            if (ObjectUtil.isNotEmpty(simpleTenantBos)) {
                simpleTenantVos = BeanUtil.copyToList(simpleTenantBos, SimpleTenantVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(simpleTenantVos);
    }

    @Override
    public R queryParentByIds(List<Integer> childMenuIds) {
        List<MenuVo> menuVos = null;
        try {
            List<MenuPo> menuPos = menuService.getParentByIds(childMenuIds);
            if (!ObjectUtil.isEmpty(menuPos)) {
                menuVos = BeanUtil.copyToList(menuPos, MenuVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuVos);
    }

    @Override
    public R queryParentById(Integer childMenuId) {
        MenuVo menuVo = null;
        try {
            MenuPo menuPo = menuService.getParentById(childMenuId);
            if (!ObjectUtil.isEmpty(menuPo)) {
                menuVo = BeanUtil.copyProperties(menuPo, MenuVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuVo);
    }

    @Override
    public R queryByParentIds(List<Integer> parentMenuIds) {
        List<MenuVo> menuVos = null;
        try {
            List<MenuPo> menuPos = menuService.getByParentIds(parentMenuIds);
            if (!ObjectUtil.isEmpty(menuPos)) {
                menuVos = BeanUtil.copyToList(menuPos, MenuVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuVos);
    }

    @Override
    public R queryByParentId(Integer parentMenuId) {
        MenuVo menuVo = null;
        try {
            MenuPo menuPo = menuService.getByParentId(parentMenuId);
            if (!ObjectUtil.isEmpty(menuPo)) {
                menuVo = BeanUtil.copyProperties(menuPo, MenuVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuVo);
    }

    @Override
    public R queryByIds(List<Integer> menuIds) {
        List<MenuVo> menuVos = null;
        try {
            List<MenuPo> menuPos = menuService.getByIds(menuIds);
            if (!ObjectUtil.isEmpty(menuPos)) {
                menuVos = BeanUtil.copyToList(menuPos, MenuVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuVos);
    }

    @Override
    public R queryById(Integer menuId) {
        MenuVo menuVo = null;
        try {
            MenuPo menuPo = menuService.getById(menuId);
            if (!ObjectUtil.isEmpty(menuPo)) {
                menuVo = BeanUtil.copyProperties(menuPo, MenuVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuVo);
    }

    @Override
    public R queryAbilityByType(Integer typeCode) {
        List<MenuAbilityVo> menuAbilityVos = null;
        try {
            menuAbilityVos = menuService.getAbilityByTypeCode(typeCode);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuAbilityVos);
    }

    @Override
    public R queryRenderRule(Integer typeCode) {
        MenuRenderRuleVo menuRenderRuleVo = null;
        try {
            menuRenderRuleVo = menuService.getRenderRule(typeCode);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuRenderRuleVo);
    }

    @Override
    public R querySupportParent(Integer typeCode) {
        List<MenuVo> menuVos = null;
        try {
            List<MenuPo> menuPos = menuService.getSupportParent(typeCode);
            if (!ObjectUtil.isEmpty(menuPos)) {
                menuVos = BeanUtil.copyToList(menuPos, MenuVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(menuVos);
    }

    @Override
    public R checkClientUri(String clientUri) {
        boolean result = false;
        try {
            MenuPo menuPo = menuService.getByClientUri(clientUri);
            result = ObjectUtil.isEmpty(menuPo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.ok(result);
    }
}
